#include "qconfigtools.h"

// 构造函数：初始化配置工具类
QConfigTools::QConfigTools(QObject *parent) : QObject(parent)
{
    // 获取应用程序的安装目录路径，并拼接配置文件名
    QString ini_file = QCoreApplication::applicationDirPath();
    ini_file.append("/config.ini");

    // 检查配置文件是否存在
    if(QFile(ini_file).exists())
    {
        // 如果配置文件存在，则初始化设置对象
        m_setting = new QSettings(ini_file, QSettings::IniFormat);
        // 初始化内容
        this->ContentsInit();
    }
    else
    {
        // 如果配置文件不存在，则创建新的设置对象并保存默认配置
        m_setting = new QSettings(ini_file, QSettings::IniFormat);
        // 保存配置到文件
        this->SaveConfig();
        // 初始化内容
        this->ContentsInit();
    }
}

QConfigTools::~QConfigTools()
{
    m_setting = nullptr;
    this->deleteLater();
}

QString QConfigTools::port() const
{
    return m_port;
}

void QConfigTools::setPort(const QString &port)
{
    m_port = port;
}

QString QConfigTools::ip() const
{
    return m_ip;
}

void QConfigTools::setIp(const QString &ip)
{
    m_ip = ip;
}

QString QConfigTools::Maxnumber() const
{
    return m_Maxnumber;
}

void QConfigTools::setMaxnumber(const QString &Maxnumber)
{
    m_Maxnumber = Maxnumber;
}

QString QConfigTools::Minnumber() const
{
    return m_Minnumber;
}

void QConfigTools::setMinnumber(const QString &Minnumber)
{
    m_Minnumber = Minnumber;
}

QString QConfigTools::working() const
{
    return m_working;
}

void QConfigTools::setWorking(const QString &working)
{
    m_working = working;
}

QString QConfigTools::product() const
{
    return m_product;
}

void QConfigTools::setProduct(const QString &product)
{
    m_product = product;
}

/**
 * @brief 初始化脚本配置
 *
 * 该函数负责检查和初始化应用程序的脚本目录及文件
 * 它会确保脚本目录存在，并创建必要的文件
 */
void QConfigTools::ScriptInit()
{
    // 获取应用程序的安装目录路径
    QString path = QCoreApplication::applicationDirPath();
    // 在安装目录下追加(luaScripts)目录路径
    path.append("/luaScripts");
    // 创建一个目录对象，用于后续的目录操作
    QDir dr(path);

    // 检查目录是否存在
    if(dr.exists())
    {
        // 如果目录存在，输出日志信息
        qDebug() << "路径存在" << path;
    }
    else
    {
        // 如果目录不存在，创建目录，并输出日志信息
        dr.mkdir(path);
        qDebug() << "创建路径" << path;
    }

    // 在目录路径下追加文件名，形成完整的文件路径
    path.append("/command.lua");
    // 创建一个文件对象，用于后续的文件操作
    QFile file(path);

    // 检查文件是否存在
    if(file.exists())
    {
        // 如果文件存在，输出日志信息
        qDebug() << "文件存在" << path;
    }
    else
    {
        // 如果文件不存在，创建文件
        file.open(QIODevice::WriteOnly);
        file.close();
    }
}

// 保存配置信息到配置文件中
void QConfigTools::SaveConfig()
{
    // 开始写入指定的配置节
    m_setting->beginGroup(this->m_section);
    // 保存产品名称到配置文件
    m_setting->setValue("Product", m_product);
    // 保存工作状态到配置文件
    m_setting->setValue("Working", m_working);
    // 保存最小编号到配置文件
    m_setting->setValue("Min", m_Minnumber);
    // 保存最大编号到配置文件
    m_setting->setValue("Max", m_Maxnumber);
    // 保存IP地址到配置文件
    m_setting->setValue("Ip", m_ip);
    // 保存端口号到配置文件
    m_setting->setValue("Port", m_port);
    // 保存协议编号到配置文件
    m_setting->setValue("ProNumber", m_ProNumber);
    // 结束配置节的写入
    m_setting->endGroup();

    // 调用保存JSON文件的方法
    this->SaveJsonFile();
}

QString QConfigTools::GetMessage()
{
    QString msg = QString("%1-%2-%3").arg(this->m_product).arg(this->m_working).arg(this->m_Minnumber);
    return msg;
}

QStringList QConfigTools::WorkingList() const
{
    return m_WorkingList;
}

void QConfigTools::setWorkingList(const QStringList &WorkingList)
{
    m_WorkingList = WorkingList;
}

QStringList QConfigTools::ProductList() const
{
    return m_ProductList;
}

void QConfigTools::setProductList(const QStringList &ProductList)
{
    m_ProductList = ProductList;
}

QString QConfigTools::ProNumber() const
{
    return m_ProNumber;
}

void QConfigTools::setProNumber(const QString &ProNumber)
{
    bool bRet;
    int min = ProNumber.toInt(&bRet, 10);
    if(bRet)
    {
        m_ProNumber = QString("%1").arg(min, 4, 10, QLatin1Char('0'));
    }
    else
    {
        m_ProNumber = "0000";
    }
}

QString QConfigTools::ShowPage() const
{
    return m_ShowPage;
}

// 初始化配置工具的内容
void QConfigTools::ContentsInit()
{
    // 构造键名以获取产品信息
    QString tmp = QString("%1/").arg(this->m_section);
    tmp.append("Product");
    // 从设置中获取产品信息并存储到m_product
    m_product = m_setting->value(tmp).toString();

    // 构造键名以获取工作模式信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("Working");
    // 从设置中获取工作模式信息并存储到m_working
    m_working = m_setting->value(tmp).toString();

    // 构造键名以获取最小编号信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("Min");
    // 从设置中获取最小编号信息并存储到m_Minnumber
    m_Minnumber = m_setting->value(tmp).toString();

    // 构造键名以获取最大编号信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("Max");
    // 从设置中获取最大编号信息并存储到m_Maxnumber
    m_Maxnumber = m_setting->value(tmp).toString();

    // 构造键名以获取IP地址信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("Ip");
    // 从设置中获取IP地址信息并存储到m_ip
    m_ip = m_setting->value(tmp).toString();

    // 构造键名以获取端口信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("Port");
    // 从设置中获取端口信息并存储到m_port
    m_port = m_setting->value(tmp).toString();

    // 构造键名以获取程序编号信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("ProNumber");
    // 从设置中获取程序编号信息并存储到m_ProNumber
    m_ProNumber = m_setting->value(tmp).toString();

    // 构造键名以获取显示页面信息
    tmp = QString("%1/").arg(this->m_section);
    tmp.append("ShowPage");
    // 从设置中获取显示页面信息并存储到m_ShowPage
    m_ShowPage = m_setting->value(tmp).toString();

    // 调用初始化JSON属性的方法
    this->JsonPropertyInit();
}

/**
 * @brief 初始化JSON属性文件
 * 
 * 该函数检查JSON配置文件是否存在如果存在，则加载该文件；
 * 如果不存在，则创建一个新的JSON配置文件此函数主要用于确保
 * 应用程序启动时所需的配置文件存在
 */
void QConfigTools::JsonPropertyInit()
{
    // 创建一个QFile对象，用于操作JSON文件
    QFile m_Jsonfile(m_JsonFile);

    // 检查JSON文件是否存在
    if(m_Jsonfile.exists())
    {
        // 如果文件存在，则加载文件
        this->LoadingJsonFile();
    }
    else
    {
        // 如果文件不存在，则创建并保存一个新的JSON文件
        this->SaveJsonFile();
    }
}

// 保存JSON文件，将当前配置信息写入到指定的JSON文件中
void QConfigTools::SaveJsonFile()
{
    // 创建一个空的JSON对象
    QJsonObject json;
    // 创建一个空的JSON数组，用于存储产品列表
    QJsonArray arr;

    // 遍历产品列表，将每个产品名称添加到JSON数组中
    foreach(const QString &s, m_ProductList)
    {
        arr.append(s);
    }

    // 将产品列表的JSON数组添加到JSON对象中，键为产品名称
    json.insert(m_ProductName, arr);

    // 创建另一个空的JSON数组，用于存储工作列表
    QJsonArray warr;

    // 遍历工作列表，将每个工作名称添加到JSON数组中
    foreach(const QString &s, m_WorkingList)
    {
        warr.append(s);
    }

    // 将工作列表的JSON数组添加到JSON对象中，键为工作名称
    json.insert(m_WorkingName, warr);

    // 创建一个JSON文档，用于序列化JSON对象
    QJsonDocument doc(json);
    // 将JSON文档转换为字节数组
    QByteArray buf = doc.toJson();
    // 打开JSON文件，准备写入
    QFile file(m_JsonFile);

    // 如果文件成功打开，将JSON数据写入文件
    if(file.open(QIODevice::WriteOnly))
    {
        QTextStream out(&file);
        out << buf;
        file.close();
    }
}

// 加载 JSON 文件并解析其内容到类成员变量
void QConfigTools::LoadingJsonFile()
{
    // 读取文件内容
    QFile file(m_JsonFile);
    file.open(QIODevice::ReadOnly);
    QByteArray jsonData = file.readAll();
    file.close();

    // 将文件内容转换为 QJsonDocument
    QJsonParseError jsonerr;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &jsonerr);

    if(jsonerr.error != QJsonParseError::NoError)
    {
        qWarning("Json对象转换错误");
        return;
    }

    // 检查 JSON 文档是否有效
    if (!jsonDoc.isNull())
    {
        if (jsonDoc.isObject())
        {
            // 如果 JSON 是一个对象，将其转换为 QJsonObject
            QJsonObject jsonObject = jsonDoc.object();
            // 处理 JsonArray对象
            QJsonArray array = jsonObject.value(m_ProductName).toArray();

            if(!array.isEmpty())
            {
                for (QJsonArray::iterator it = array.begin(); it != array.end(); ++it)
                {
                    m_ProductList.append(it->toString());
                }
            }

            array = jsonObject.value(m_WorkingName).toArray();

            if(!array.isEmpty())
            {
                for (QJsonArray::iterator it = array.begin(); it != array.end(); ++it)
                {
                    m_WorkingList.append(it->toString());
                }
            }
        }
        else
        {
            qWarning("Json 内容错误");
        }
    }
    else
    {
        // 处理 JSON 文档无效的情况
        qWarning("无效文件");
    }
}
